-
Notifications
You must be signed in to change notification settings - Fork 334
feat(openapi3): add x-ms-duration extension support for duration encoding with round-trip via @extension decorator #9412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…with @encode decorator Co-authored-by: baywet <7905502+baywet@users.noreply.github.com>
Co-authored-by: baywet <7905502+baywet@users.noreply.github.com>
|
@copilot add another unit test to validate there are no regressions if it does not exist already. The following OpenAPI description foo:
type: string
format: durationShould result in this TypeSpec bar: durationNote there are no encode attribute in that case. |
commit: |
Co-authored-by: baywet <7905502+baywet@users.noreply.github.com>
Added regression test in commit 09b3593. The test validates that |
|
You can try these changes here
|
Pull request was converted to draft
|
@copilot revert the change where the encode decorator generates the extension. Instead make sure the import also adds an extension decorator when the extension is present in the source document. |
…d of auto-generating extension - Revert export functionality that auto-generated x-ms-duration extension - Update import to add @extension decorator when x-ms-duration is present - Both @extension and @encode decorators are now added during import - Removes extension filtering for x-ms-duration - Update tests to expect both decorators - Enables proper round-tripping via @extension decorator Co-authored-by: baywet <7905502+baywet@users.noreply.github.com>
Reverted export functionality in commit 3eab35d. The importer now adds both |
|
@copilot while running integration tests, I'm running into the following issue, regardless of the format, the encode as is always float32. Investigate and correct this behaviour. |
…encoding format - Pass effectiveType to getDurationSchemaDecorators to handle OpenAPI 3.1 type arrays - Fixes issue where format was always float32 regardless of actual format - Update test expectations to match TypeSpec compiler's decorator ordering - Now correctly generates int32, float32, float64, decimal based on schema format Co-authored-by: baywet <7905502+baywet@users.noreply.github.com>
Fixed in commit 446c2e1. The issue was that |
|
@copilot Add a data-types test for this format combination: type: number
format: int64
x-ms-duration: secondsThe result should be |
… with x-ms-duration - Add support for integer formats (int8, int16, int32, int64, uint8, uint16, uint32, uint64) when type is number - Fixes scenario where type: number, format: int64, x-ms-duration: seconds now correctly generates @encode("seconds", int64) - Add test case for number with int64 format and x-ms-duration extension - All 33 data-types tests pass Co-authored-by: baywet <7905502+baywet@users.noreply.github.com>
... Added test in commit 8772da4. The test initially failed (was generating |
…ding with round-trip via @extension decorator (#9412) ## OpenAPI duration property import with x-ms-duration extension This PR implements support for duration types in the OpenAPI importer using the `x-ms-duration` extension, with round-trip capability via the `@extension` decorator. ### Changes completed: - [x] Add test cases for all duration scenarios with x-ms-duration extension - [x] Update getNumberType and getIntegerType functions to handle x-ms-duration extension (import) - [x] Add decorator generation for x-ms-duration with seconds/milliseconds encoding (import) - [x] Add @extension decorator for x-ms-duration to enable round-tripping - [x] Fix encoding type detection to use effectiveType (handles type arrays) - [x] Support integer formats (int8-uint64) for number type with x-ms-duration - [x] Run tests to validate all scenarios - [x] Format code before final commit - [x] Add changelog entry using chronus - [x] Add regression test for string duration format (no encode decorator) ### Implementation details: **Import (OpenAPI → TypeSpec):** - Modified `getNumberType()` and `getIntegerType()` in `generate-types.ts` to check for `x-ms-duration` extension (values: `seconds` or `milliseconds`) - Updated `getDurationSchemaDecorators()` function in `decorators.ts` to: - Accept `effectiveType` parameter to properly handle OpenAPI 3.1 type arrays like `["integer", "null"]` - Generate appropriate `@encode` decorators based on both the `x-ms-duration` value and the schema's format - Support all integer formats (int8, int16, int32, int64, uint8, uint16, uint32, uint64) even when type is "number" - Support all number formats (float, double, decimal, decimal128) - Use effectiveType instead of schema.type to avoid defaulting to float32 when type is an array - Removed filtering of `x-ms-duration` from `getExtensions()` so it's also added as an `@extension` decorator for proper round-tripping **Export (TypeSpec → OpenAPI):** - Round-tripping is achieved via the standard `@extension` decorator mechanism - When TypeSpec has `@extension("x-ms-duration", "seconds")`, the standard extension handling emits it to OpenAPI ### Test coverage: - Added comprehensive test suite in `data-types.test.ts` covering all import scenarios from requirements table (33 tests) - Added test cases in `generate-type.test.ts` for inline type expressions (82 tests) - All tests pass successfully - Manual testing confirms correct encoding types for all formats (int8-uint64, float32, float64, decimal, etc.) ### Supported scenarios: | OAS type | OAS format | OAS x-ms-duration | TypeSpec Output | | ---------- | ------------- | --------------------------- | ---------------- | | string | duration | not applicable | `duration` | | integer | int32 | absent | `int32` | | integer | int32 | present, set to seconds | `@extension("x-ms-duration", "seconds") @encode("seconds", int32) ... duration` | | number | int64 | present, set to seconds | `@extension("x-ms-duration", "seconds") @encode("seconds", int64) ... duration` | | number | float | absent | `float32` | | number | float | present, set to seconds | `@extension("x-ms-duration", "seconds") @encode("seconds", float32) ... duration` | | number | decimal | present, set to seconds | `@extension("x-ms-duration", "seconds") @encode("seconds", decimal) ... duration` | | number | double | present, set to milliseconds | `@extension("x-ms-duration", "milliseconds") @encode("milliseconds", float64) ... duration` | ### Example transformations: **Integer type with int32 format:** ```yaml # OpenAPI DurationInt32Seconds: type: integer format: int32 x-ms-duration: seconds ``` ```typespec // TypeSpec @extension("x-ms-duration", "seconds") @encode("seconds", int32) scalar DurationInt32Seconds extends duration; ``` **Number type with int64 format:** ```yaml # OpenAPI DurationNumberInt64: type: number format: int64 x-ms-duration: seconds ``` ```typespec // TypeSpec @extension("x-ms-duration", "seconds") @encode("seconds", int64) scalar DurationNumberInt64 extends duration; ``` **Number type with decimal format:** ```yaml # OpenAPI DurationDecimalSeconds: type: number format: decimal x-ms-duration: seconds ``` ```typespec // TypeSpec @extension("x-ms-duration", "seconds") @encode("seconds", decimal) scalar DurationDecimalSeconds extends duration; ``` <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>importer - OpenAPI duration properties should result in a duration properties</issue_title> > <issue_description>### Clear and concise description of the problem > > When importing a property with the following schema: > > ```yaml > foo: > type: number > format: duration > ``` > > Currently results in this > > ```typespec > foo: numeric > ``` > > But should result in this > > ```typespec > @encode("seconds", float32) > foo: duration > ``` > > ### Checklist > > - [x] Follow our [Code of Conduct](https://github.com/microsoft/typespec/blob/main/CODE_OF_CONDUCT.md) > - [x] Read the [docs](https://typespec.io/docs/). > - [x] Check that there isn't already an issue that request the same feature to avoid creating a duplicate.</issue_description> > > <agent_instructions>use conventional commits. > run the formatting command before any commit. > start by writing the unit tests first. > when done, run the following command to add a feature entry to the changelog `npx @chronus/chronus add`</agent_instructions> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > </comments> > </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes #9411 <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/microsoft/typespec/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: baywet <7905502+baywet@users.noreply.github.com> Co-authored-by: Vincent Biret <vibiret@microsoft.com>
OpenAPI duration property import with x-ms-duration extension
This PR implements support for duration types in the OpenAPI importer using the
x-ms-durationextension, with round-trip capability via the@extensiondecorator.Changes completed:
Implementation details:
Import (OpenAPI → TypeSpec):
getNumberType()andgetIntegerType()ingenerate-types.tsto check forx-ms-durationextension (values:secondsormilliseconds)getDurationSchemaDecorators()function indecorators.tsto:effectiveTypeparameter to properly handle OpenAPI 3.1 type arrays like["integer", "null"]@encodedecorators based on both thex-ms-durationvalue and the schema's formatx-ms-durationfromgetExtensions()so it's also added as an@extensiondecorator for proper round-trippingExport (TypeSpec → OpenAPI):
@extensiondecorator mechanism@extension("x-ms-duration", "seconds"), the standard extension handling emits it to OpenAPITest coverage:
data-types.test.tscovering all import scenarios from requirements table (33 tests)generate-type.test.tsfor inline type expressions (82 tests)Supported scenarios:
durationint32@extension("x-ms-duration", "seconds") @encode("seconds", int32) ... duration@extension("x-ms-duration", "seconds") @encode("seconds", int64) ... durationfloat32@extension("x-ms-duration", "seconds") @encode("seconds", float32) ... duration@extension("x-ms-duration", "seconds") @encode("seconds", decimal) ... duration@extension("x-ms-duration", "milliseconds") @encode("milliseconds", float64) ... durationExample transformations:
Integer type with int32 format:
Number type with int64 format:
Number type with decimal format:
Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.